﻿using Common;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Threading;

namespace Bussiness
{
    public delegate void OnPortDataHandler(string portname, byte[] buffer);
    public class SerialPortlib
    {
        SerialPort _port = null;
        string _activeArgs = string.Empty;
        List<byte> _GlBuffer = new List<byte>();
        public string PortName { get { return _port.PortName; } set { } }
        public string PortArgs { get { return _activeArgs; } set { } }
        public int BytesCanRead { get { return this._GlBuffer.Count; } }

        public bool IsOpen { get { return _port.IsOpen; } }

        event OnPortDataHandler _OnPortData = null;

        public event OnPortDataHandler OnPortData
        {
            //Add是向Event挂EventHandler（由EventHanlder的逻辑在Event触发时来进行处理），Remove是卸载EventHandler。
            add { _OnPortData = null; _OnPortData += value; }
            remove { _OnPortData = null; }
        }

        /// <summary>
        /// 关闭
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool Close(string args)
        {
            if (_port != null)
            {
                _port.Dispose();
                _port.Close();
            }

            return true;
        }

        /// <summary>
        /// 开启
        /// </summary>
        /// <param name="args"></param>
        /// <returns></returns>
        public bool Open(string args)
        {
            if (!string.IsNullOrEmpty(args))
            {
                _activeArgs = args;
            }
            else
            {
                args = _activeArgs;
            }

            if (string.IsNullOrEmpty(args)) return false;
            string[] param = args.Split(',');
            if (param == null || param.Length != 6) return false;
            string portname = param[0];
            if (portname.Length > 4)
                portname = "" + portname;
            int baudrate = 0;
            if (!int.TryParse(param[1], out baudrate)) return false;
            int databits = 0;
            if (!int.TryParse(param[2], out databits)) return false;
            Parity pt = Parity.None;
            int ipt = 0;
            if (!int.TryParse(param[3], out ipt)) return false;
            pt = (Parity)ipt;
            StopBits spt = StopBits.One;
            int ispt = 0;
            if (!int.TryParse(param[4], out ispt)) return false;
            spt = (StopBits)ispt;
            _port = new SerialPort();
            _port.PortName = portname;
            _port.BaudRate = baudrate;
            _port.Parity = pt;
            _port.DataBits = databits;
            _port.StopBits = spt;
            _port.ReceivedBytesThreshold = 1;
            _port.DataReceived += DataReceived;
            _port.Open();
            return true;
        }

        /// <summary>
        /// 接收
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                lock (_GlBuffer)
                {
                    int count = this._port.BytesToRead;
                    byte[] buffer = new byte[count];
                    this._port.Read(buffer, 0, buffer.Length);
                    LOG.Write(this.PortName + " recvie data:" + BitConverter.ToString(buffer));
                    this._GlBuffer.AddRange(buffer);
                    //这地方有问题，莫名的会不为null
                    if (this._OnPortData != null)
                    {
                        LOG.Write(this.PortName + " UpLoad data:" + BitConverter.ToString(buffer) + " OnPortData");
                        this._OnPortData(this.PortName, buffer);
                    }
                    else
                    {
                        LOG.Write(this.PortName + " UpLoad data:" + BitConverter.ToString(buffer) + " GlBuffer Add");
                    }
                }
            }
            catch (Exception ex)
            {
                LOG.Write("exception:" + ex.Message + ex.StackTrace);
            }
        }

        /// <summary>
        /// 接收数据
        /// </summary>
        /// <returns></returns>
        public byte[] ReadData()
        {
            lock (this._GlBuffer)
            {
                if (this._GlBuffer.Count <= 0) return null;
                byte[] bf = this._GlBuffer.ToArray();
                this._GlBuffer.Clear();
                return bf;
            }
        }

        /// <summary>
        /// 写数据
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public bool WriteData(byte[] buffer)
        {
            try
            {
                if (_port == null || !_port.IsOpen) return false;
                _port.Write(buffer, 0, buffer.Length);
                LOG.Write(this.PortName + " Write data:" + BitConverter.ToString(buffer));
            }
            catch (Exception ex)
            {
                LOG.Write("PortSerial WriteData" + ex.Message + ex.StackTrace);
                _port.Close();
                Thread.Sleep(100);
                _port.Open();
                return false;
            }
            return true;
        }
    }
}
